package com.campus.food.service.impl;

import com.campus.food.mapper.ReviewMapper;
import com.campus.food.mapper.OrderMapper;
import com.campus.food.mapper.UserMapper;
import com.campus.food.mapper.MerchantMapper;
import com.campus.food.model.entity.Review;
import com.campus.food.model.entity.Order;
import com.campus.food.model.entity.User;
import com.campus.food.model.entity.Merchant;
import com.campus.food.service.ReviewService;
import com.campus.food.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 评价服务实现类
 * 
 * @author Claude3.7 Sonnet
 * @since 2025-05-29
 */
@Service
@Transactional
public class ReviewServiceImpl implements ReviewService {
    
    @Autowired
    private ReviewMapper reviewMapper;
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private MerchantMapper merchantMapper;
    
    @Override
    public Review addReview(Review review) {
        // 验证评价信息
        validateReview(review);
        
        // 检查用户是否存在
        User user = userMapper.selectById(review.getUserId());
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 检查订单是否存在
        Order order = orderMapper.selectById(review.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 验证权限（确保是用户自己的订单）
        if (!order.getUserId().equals(review.getUserId())) {
            throw new BusinessException("无权限评价此订单");
        }
        
        // 检查订单是否已完成
        if (order.getStatus() != 4) { // 状态4表示已完成
            throw new BusinessException("只有已完成的订单才能评价");
        }
        
        // 检查是否已经评价过
        if (reviewMapper.existsByOrderId(review.getOrderId())) {
            throw new BusinessException("该订单已评价，不能重复评价");
        }
        
        // 设置商家ID
        review.setMerchantId(order.getMerchantId());
        
        // 保存评价
        int result = reviewMapper.insert(review);
        if (result <= 0) {
            throw new BusinessException("添加评价失败");
        }
        
        // 更新商家评分
        updateMerchantRating(review.getMerchantId());
        
        return review;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Review getReviewById(Long id) {
        if (id == null) {
            throw new BusinessException("评价ID不能为空");
        }
        
        Review review = reviewMapper.selectById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        return review;
    }
    
    @Override
    public boolean updateReview(Review review) {
        if (review.getId() == null) {
            throw new BusinessException("评价ID不能为空");
        }
        
        // 验证评价信息
        validateReview(review);
        
        // 检查评价是否存在
        Review existingReview = reviewMapper.selectById(review.getId());
        if (existingReview == null) {
            throw new BusinessException("评价不存在");
        }
        
        // 验证权限（确保只能修改自己的评价）
        if (!existingReview.getUserId().equals(review.getUserId())) {
            throw new BusinessException("无权限修改此评价");
        }
        
        boolean result = reviewMapper.updateById(review) > 0;
        
        // 更新商家评分
        if (result) {
            updateMerchantRating(existingReview.getMerchantId());
        }
        
        return result;
    }
    
    @Override
    public boolean deleteReview(Long id, Long userId) {
        if (id == null) {
            throw new BusinessException("评价ID不能为空");
        }
        
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        // 检查评价是否存在
        Review review = reviewMapper.selectById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        // 验证权限（确保只能删除自己的评价）
        if (!review.getUserId().equals(userId)) {
            throw new BusinessException("无权限删除此评价");
        }
        
        boolean result = reviewMapper.deleteById(id) > 0;
        
        // 更新商家评分
        if (result) {
            updateMerchantRating(review.getMerchantId());
        }
        
        return result;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Review getReviewByOrderId(Long orderId) {
        if (orderId == null) {
            throw new BusinessException("订单ID不能为空");
        }
        
        return reviewMapper.selectByOrderId(orderId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getMerchantReviews(Long merchantId, int page, int size, Integer rating) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.selectPageByMerchant(merchantId, offset, size, rating);
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getMerchantReviewCount(Long merchantId, Integer rating) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        Long count = reviewMapper.selectCountByMerchant(merchantId, rating);
        return count != null ? count : 0;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByUserId(Long userId, int page, int size, Integer rating) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.selectPageByUserAndRating(userId, offset, size, rating);
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getReviewCountByUserId(Long userId, Integer rating) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        Long count = reviewMapper.selectCountByUserAndRating(userId, rating);
        return count != null ? count : 0;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByMerchantId(Long merchantId, int page, int size, Integer rating) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.selectPageByMerchant(merchantId, offset, size, rating);
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getReviewCountByMerchantId(Long merchantId, Integer rating) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        Long count = reviewMapper.selectCountByMerchant(merchantId, rating);
        return count != null ? count : 0;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getUserReviews(Long userId, int page, int size) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.selectPageByUser(userId, offset, size);
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getUserReviewCount(Long userId) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        Long count = reviewMapper.selectCountByUser(userId);
        return count != null ? count : 0;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Double getMerchantAvgRating(Long merchantId) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        Double avgRating = reviewMapper.selectAvgRatingByMerchant(merchantId);
        return avgRating != null ? avgRating : 5.0; // 默认5.0分
    }
    
    @Override
    @Transactional(readOnly = true)
    public Double getAverageRatingByMerchantId(Long merchantId) {
        return getMerchantAvgRating(merchantId);
    }
    
    @Override
    public boolean replyReview(Long id, String reply, Long merchantId) {
        if (id == null) {
            throw new BusinessException("评价ID不能为空");
        }
        
        if (!StringUtils.hasText(reply)) {
            throw new BusinessException("回复内容不能为空");
        }
        
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        // 检查评价是否存在
        Review review = reviewMapper.selectById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        // 验证权限（确保只能回复自己商家的评价）
        if (!review.getMerchantId().equals(merchantId)) {
            throw new BusinessException("无权限回复此评价");
        }
        
        // 验证回复内容长度
        if (reply.length() > 500) {
            throw new BusinessException("回复内容不能超过500个字符");
        }
        
        return reviewMapper.updateReply(id, reply) > 0;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getMerchantRatingStats(Long merchantId) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        return reviewMapper.selectRatingCountByMerchant(merchantId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean hasReviewedOrder(Long orderId) {
        if (orderId == null) {
            throw new BusinessException("订单ID不能为空");
        }
        
        return reviewMapper.existsByOrderId(orderId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean checkReviewExists(Long orderId) {
        return hasReviewedOrder(orderId);
    }
    
    @Override
    public boolean deleteReviewsBatch(List<Long> ids, Long userId) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("评价ID列表不能为空");
        }
        
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        // 验证所有评价都属于当前用户并记录商家ID用于更新评分
        Long merchantId = null;
        for (Long id : ids) {
            Review review = reviewMapper.selectById(id);
            if (review == null) {
                throw new BusinessException("评价不存在：" + id);
            }
            if (!review.getUserId().equals(userId)) {
                throw new BusinessException("无权限删除评价：" + id);
            }
            if (merchantId == null) {
                merchantId = review.getMerchantId();
            }
        }
        
        boolean result = reviewMapper.deleteBatch(ids) > 0;
        
        // 更新商家评分
        if (result && merchantId != null) {
            updateMerchantRating(merchantId);
        }
        
        return result;
    }
    
    @Override
    public boolean deleteReviewsBatch(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("评价ID列表不能为空");
        }
        
        // 记录商家ID用于更新评分
        Long merchantId = null;
        for (Long id : ids) {
            Review review = reviewMapper.selectById(id);
            if (review != null && merchantId == null) {
                merchantId = review.getMerchantId();
            }
        }
        
        boolean result = reviewMapper.deleteBatch(ids) > 0;
        
        // 更新商家评分
        if (result && merchantId != null) {
            updateMerchantRating(merchantId);
        }
        
        return result;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getAllReviews(int page, int size, Long userId, Long merchantId) {
        int offset = (page - 1) * size;
        return reviewMapper.selectAllForAdmin(offset, size, userId, merchantId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getAllReviews(int page, int size, Long userId, Long merchantId, Integer rating) {
        int offset = (page - 1) * size;
        return reviewMapper.selectAllForAdminWithRating(offset, size, userId, merchantId, rating);
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getAllReviewCount(Long userId, Long merchantId, Integer rating) {
        Long count = reviewMapper.selectAllCountForAdmin(userId, merchantId, rating);
        return count != null ? count : 0;
    }
    
    @Override
    public boolean updateMerchantRating(Long merchantId) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        // 检查商家是否存在
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new BusinessException("商家不存在");
        }
        
        // 计算平均评分
        Double avgRating = reviewMapper.selectAvgRatingByMerchant(merchantId);
        if (avgRating == null) {
            avgRating = 5.0; // 没有评价时默认5.0分
        }
        
        // 更新商家评分
        return merchantMapper.updateRating(merchantId, avgRating) > 0;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getLatestReviews(int limit) {
        if (limit <= 0) {
            limit = 10; // 默认返回10条
        }
        
        // 这里可以根据时间排序获取最新评价，简化实现
        return reviewMapper.selectAllForAdmin(0, limit, null, null);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getLatestReviews(int limit, Long merchantId) {
        if (limit <= 0) {
            limit = 10; // 默认返回10条
        }
        
        return reviewMapper.selectLatestReviews(limit, merchantId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByRating(Integer rating, int page, int size) {
        if (rating == null || rating < 1 || rating > 5) {
            throw new BusinessException("评分必须在1-5之间");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.selectByRating(rating, offset, size);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> searchReviews(String keyword, int page, int size, Long merchantId, Integer rating) {
        if (!StringUtils.hasText(keyword)) {
            throw new BusinessException("搜索关键词不能为空");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.searchReviews(keyword, offset, size, merchantId, rating);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsWithImages(Long merchantId, int page, int size) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        int offset = (page - 1) * size;
        return reviewMapper.selectReviewsWithImages(merchantId, offset, size);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean canReviewOrder(Long orderId, Long userId) {
        if (orderId == null) {
            throw new BusinessException("订单ID不能为空");
        }
        
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        // 检查订单是否存在
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            return false;
        }
        
        // 检查是否是用户自己的订单
        if (!order.getUserId().equals(userId)) {
            return false;
        }
        
        // 检查订单是否已完成
        if (order.getStatus() != 4) {
            return false;
        }
        
        // 检查是否已经评价过
        if (reviewMapper.existsByOrderId(orderId)) {
            return false;
        }
        
        return true;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getHighRatingReviews(Long merchantId, Integer minRating, int limit) {
        if (minRating == null || minRating < 1 || minRating > 5) {
            minRating = 4; // 默认4分以上
        }
        
        if (limit <= 0) {
            limit = 10; // 默认返回10条
        }
        
        int offset = 0;
        int size = limit;
        
        return reviewMapper.selectPageByMerchant(merchantId, offset, size, minRating);
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getRepliedReviewCount(Long merchantId) {
        if (merchantId == null) {
            throw new BusinessException("商家ID不能为空");
        }
        
        Long count = reviewMapper.selectRepliedCountByMerchant(merchantId);
        return count != null ? count : 0;
    }
    
    /**
     * 验证评价信息
     */
    private void validateReview(Review review) {
        if (review == null) {
            throw new BusinessException("评价信息不能为空");
        }
        
        if (review.getUserId() == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        if (review.getOrderId() == null) {
            throw new BusinessException("订单ID不能为空");
        }
        
        if (review.getRating() == null || review.getRating() < 1 || review.getRating() > 5) {
            throw new BusinessException("评分必须在1-5之间");
        }
        
        // 验证评价内容长度
        if (StringUtils.hasText(review.getContent()) && review.getContent().length() > 500) {
            throw new BusinessException("评价内容不能超过500个字符");
        }
        
        // 验证图片路径长度
        if (StringUtils.hasText(review.getImages()) && review.getImages().length() > 1000) {
            throw new BusinessException("图片路径过长");
        }
    }
} 